{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "代码所做修改：1、更稳健的路径查找（避免 FileNotFoundError）\n",
    "             2、更稳健的编码处理（避免乱码/解码错误）\n",
    "             3、轻量清洗以保障后续操作稳定\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "# 设置列/行的显示\n",
    "pd.set_option('display.max_columns', None)\n",
    "# pd.set_option('display.max_rows', None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ---------- 稳健的路径与编码处理 ----------\n",
    "from pathlib import Path\n",
    "\n",
    "def _resolve_csv_path():\n",
    "    \"\"\"优先使用 datasets/000001.csv；不存在时回退到当前目录 000001.csv。\"\"\"\n",
    "    for p in (Path('datasets/000001.csv'), Path('000001.csv')):\n",
    "        if p.exists():\n",
    "            return str(p)\n",
    "    raise FileNotFoundError(\"未找到 000001.csv，请将文件放在 datasets/ 目录或与代码同级。\")\n",
    "\n",
    "def _detect_encoding_or_none(file):\n",
    "    \"\"\"若安装了 chardet 则返回(encoding, confidence)，否则返回(None, 0.0)。\"\"\"\n",
    "    try:\n",
    "        import chardet\n",
    "        raw = Path(file).read_bytes()\n",
    "        res = chardet.detect(raw)\n",
    "        return res.get('encoding'), float(res.get('confidence', 0) or 0)\n",
    "    except Exception:\n",
    "        return None, 0.0\n",
    "\n",
    "def _read_csv_safely(file):\n",
    "    \"\"\"\n",
    "    稳健读取：按“探测结果→常见编码回退→默认”顺序尝试，尽量避免乱码与解码错误。\n",
    "    \"\"\"\n",
    "    enc, conf = _detect_encoding_or_none(file)\n",
    "    print(f\"Encoding: {enc or 'unknown'}, Confidence: {conf:.2f}\")\n",
    "    enc_candidates = [enc, 'utf-8-sig', 'utf-8', 'gb18030', 'gbk', 'latin1']\n",
    "    last_err = None\n",
    "    for e in enc_candidates:\n",
    "        if not e:\n",
    "            continue\n",
    "        try:\n",
    "            df = pd.read_csv(file, encoding=e)\n",
    "            print(f'使用编码成功: {e}  文件: {file}')\n",
    "            return df\n",
    "        except Exception as ex:\n",
    "            last_err = ex\n",
    "            continue\n",
    "    try:\n",
    "        return pd.read_csv(file)  # pandas 默认（多数情况为 utf-8）\n",
    "    except Exception as ex:\n",
    "        raise RuntimeError(f'CSV读取失败，最后错误：{ex or last_err}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 查看数据的编码与导入数据（保持两步结构）\n",
    "# =========================\n",
    "file_path = _resolve_csv_path()\n",
    "enc, conf = _detect_encoding_or_none(file_path)\n",
    "print(f\"Encoding: {enc or 'unknown'}, Confidence: {conf:.2f}\")\n",
    "\n",
    "data = _read_csv_safely(file_path)\n",
    "data  # 在交互环境会显示表格"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 轻量规范化：仅做必要的类型与缺失值处理，以保证后续操作稳定\n",
    "# =========================\n",
    "# 1) 将 Day 解析为日期（原始格式通常为 1990/12/19）\n",
    "if data['Day'].dtype != 'datetime64[ns]':\n",
    "    data['Day'] = pd.to_datetime(data['Day'], format='%Y/%m/%d', errors='coerce')\n",
    "\n",
    "# 2) 数值列统一为 float，避免 object 类型影响排序/计算\n",
    "for c in ['Preclose', 'Open', 'Highest', 'Lowest', 'Close']:\n",
    "    if c in data.columns:\n",
    "        data[c] = pd.to_numeric(data[c], errors='coerce')\n",
    "\n",
    "# 3) 若 Preclose 整列缺失：用前一日 Close 生成（常见做法）\n",
    "if 'Preclose' in data.columns and data['Preclose'].isna().all():\n",
    "    data = data.sort_values('Day')\n",
    "    data['Preclose'] = data['Close'].shift(1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 了解变量的格式\n",
    "# =========================\n",
    "type(data)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 打印数据框的列名\n",
    "print(data.columns)\n",
    "print(data.columns.values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# 选择某一列（演示多种方式）\n",
    "# =========================\n",
    "data['Day']           # Series\n",
    "data.Day              # Series（属性访问）\n",
    "data[['Day']]         # DataFrame（二维）\n",
    "type(data['Day'])\n",
    "type(data[['Day']])\n",
    "data[['Day']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "# 如何选择多列？\n",
    "# =========================\n",
    "data[['Day','Close']]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 如何选择行？按行数\n",
    "# =========================\n",
    "data[0:7]\n",
    "data.iloc[0:5,0:6]        # 按行列号访问\n",
    "data.at[2,'Open']         # 按行标签与列名访问（单元素更高效）\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 条件筛选：特定日期的开盘价（兼容 Day 为 datetime）\n",
    "data[data['Day'].dt.strftime('%Y/%m/%d') == \"1990/12/21\"].Open\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 再次确保 Day 为日期（若前面已转换，此步等效 no-op）\n",
    "data['Day'] = pd.to_datetime(data['Day'], format='%Y/%m/%d', errors='coerce')\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 降序/升序排序\n",
    "data = data.sort_values(by=['Day'], axis=0, ascending=False)\n",
    "data\n",
    "data = data.sort_values(by=['Day'], ascending=True)\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将 Day 设置为索引\n",
    "data.set_index('Day', inplace = True)\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 时间范围筛选\n",
    "data['1995-12':'2000-04']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 查看帮助（方法说明）\n",
    "# =========================\n",
    "help(data.sort_values)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
